package edu.uta.cfl.GUI;

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JToolBar;
import javax.swing.JTree;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.border.BevelBorder;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.EtchedBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeSelectionModel;

import edu.uta.cfl.data.Parameter;
import edu.uta.cfl.data.SUT;
import edu.uta.cfl.data.TestSet;
import edu.uta.cfl.engine.SUTInfoReader;

public class BEN {
	private JFrame frame;
	private String ipFileName;
	private String opNewTC;
	private String opSusCombo;

	/**
	 * @return the ipFileName
	 */
	public String getIpFileName() {
		return ipFileName;
	}

	/**
	 * @param ipFileName
	 *            the ipFileName to set
	 */
	public void setIpFileName(String ipFileName) {
		this.ipFileName = ipFileName;
	}

	/**
	 * @return the opNewTC
	 */
	public String getOpNewTC() {
		return opNewTC;
	}

	/**
	 * @param opNewTC
	 *            the opNewTC to set
	 */
	public void setOpNewTC(String opNewTC) {
		this.opNewTC = opNewTC;
	}

	/**
	 * @return the opSusCombo
	 */
	public String getOpSusCombo() {
		return opSusCombo;
	}

	/**
	 * @param opSusCombo
	 *            the opSusCombo to set
	 */
	public void setOpSusCombo(String opSusCombo) {
		this.opSusCombo = opSusCombo;
	}

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					UIManager.setLookAndFeel(UIManager
							.getSystemLookAndFeelClassName()); // Set UI to
																// current
																// system
																// appearance
					BEN window = new BEN();
					window.frame.setVisible(true);

				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public BEN() {
		initialize();
	}

	@SuppressWarnings("static-access")
	public void initialize() {
		// Frame
		frame = new JFrame("");// Creating Frame
		frame.setSize(1000, 600); // setBounds(int x co-ordinate, int y
									// co-ordinate, int height, int width)
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setDefaultLookAndFeelDecorated(true);
		frame.setLocationRelativeTo(null); // to position the window center on
											// the screen
		frame.setTitle("BEN");
		frame.setLayout(new BorderLayout());
		frame.setVisible(true);
		// Variables
		// Menu Bar Components
		JMenuBar menuBar = new JMenuBar();
		JMenu fileMenu = new JMenu(" File");
		JMenu helpMenu = new JMenu(" Help");
		JMenuItem fileOpen = new JMenuItem();
		JMenuItem fileExit = new JMenuItem();
		JMenuItem helpAbout = new JMenuItem();
		final String aboutApplication = "Version 1.0";
		Font defaultfont = new Font("Tahoma", 1, 25);
		Font font = new Font("Serif", Font.ITALIC, 24);

		// ToolBar Components
		JToolBar toolBar = new JToolBar();
		JButton openFileBtn = new JButton();
		JButton newFileBtn = new JButton();
		JButton infoHelpBtn = new JButton();

		// Right Panel components
		JPanel sourceCodePanel = new JPanel();
		JPanel initialTestCasePanel = new JPanel();
		JPanel specificationPanel = new JPanel();

		JLabel sourceCodeLabel = new JLabel("Source code");

		final JTabbedPane mainTab = new JTabbedPane();
		final JTabbedPane innerSpecificationTab = new JTabbedPane();
		mainTab.add("Source Code", sourceCodePanel);
		mainTab.add("Input Parameter Model", innerSpecificationTab);
		mainTab.add("Initial Test Set", initialTestCasePanel);
		// innerSpecificationTab.setBorder(BorderFactory.createCompoundBorder((BorderFactory.createRaisedBevelBorder()),
		// (BorderFactory.createLoweredBevelBorder())));
		innerSpecificationTab.setBorder(BorderFactory.createEmptyBorder(10, 10,
				10, 10));
		sourceCodePanel.add(sourceCodeLabel);
		initialTestCasePanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5,
				5));
		mainTab.addChangeListener(new ChangeListener() {

			@Override
			public void stateChanged(ChangeEvent e) {
				// to be implemented later

			}
		});

		// Panel
		JPanel leftPanel = new JPanel();
		JPanel rightPanel = new JPanel();
		// Panels declarations for Constraints, Parameters and input test case
		// view
		JPanel parameterPanel = new JPanel();
		parameterPanel.setLayout(new BorderLayout());
		JPanel constraintsPanel = new JPanel();
		constraintsPanel.setLayout(new BorderLayout());
		initialTestCasePanel.setLayout(new BorderLayout());
		// Table logic
		final DefaultTableModel pTable = new DefaultTableModel();
		JTable parameterTable = new JTable(pTable);

		final DefaultTableModel constraintsTable = new DefaultTableModel();
		JTable tableConstraints = new JTable(constraintsTable);

		final DefaultTableModel testresultTable = new DefaultTableModel();
		JTable resultTable = new JTable(testresultTable);

		parameterTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);

		final String[] pnameArray = new String[2]; // Declaring string array
		pnameArray[0] = "Parameter Name"; // initializing the array elements
											// individually
		pnameArray[1] = "Parameter Value";
		// ScrollPane declaration
		final JScrollPane parameterPane = new JScrollPane(parameterTable);
		parameterPane
				.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
		parameterPane
				.setViewportBorder(new CompoundBorder(new CompoundBorder(null,
						new EtchedBorder(EtchedBorder.LOWERED, null, null)),
						null));
		parameterPane.setToolTipText("Parameters and Values");

		final JScrollPane constraintsPane = new JScrollPane(tableConstraints);
		constraintsPane
				.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
		constraintsPane.setToolTipText("Constraints");

		JScrollPane initialTestPane = new JScrollPane(resultTable);
		initialTestPane
				.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
		initialTestPane.setToolTipText("Initial Test Set");
		initialTestPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10,
				10));

		parameterPanel.add(parameterPane);
		parameterPanel.setSize(200, 100);
		// parameterPanel.setBorder(BorderFactory.createTitledBorder("Parameters"));

		constraintsPanel.add(constraintsPane);
		constraintsPanel.setSize(200, 100);
		// constraintsPanel.setBorder(BorderFactory.createTitledBorder("Constraints"));

		innerSpecificationTab.add("Parameters", parameterPanel);
		innerSpecificationTab.add("Constraints", constraintsPanel);

		initialTestCasePanel.add(initialTestPane);

		// Left panel components
		JLabel treeHeaderLabel = new JLabel();
		DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
		DefaultMutableTreeNode sourceCode = new DefaultMutableTreeNode(
				"Source Code");
		DefaultMutableTreeNode initialTestCase = new DefaultMutableTreeNode(
				"Initial Test Set");
		DefaultMutableTreeNode inputparametermodel = new DefaultMutableTreeNode(
				"Input Parameter Model");
		DefaultMutableTreeNode parameters = new DefaultMutableTreeNode(
				"Parameters");
		DefaultMutableTreeNode constraints = new DefaultMutableTreeNode(
				"Constraints");

		final JTree tree = new JTree(root);

		// JSplitPane
		JSplitPane splitPane = new JSplitPane();
		splitPane.setDividerLocation(180);
		splitPane.setDividerSize(3);
		splitPane.setBorder(BorderFactory.createEmptyBorder(5, 10, 10, 10)); // Empty
																				// border
																				// for
																				// the
																				// split
																				// pane

		// Definition Logic

		// Menu items definition logic
		fileOpen.setText(" Open Input File ...");
		// fileOpen.setIcon(new
		// javax.swing.ImageIcon(getClass().getResource("cse/uta/edu/Images/open_project_16.png")));
		// fileOpen.setIcon(getClass().getResource("cse/uta/edu/Images/open_project_16.png"));
		fileOpen.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
				java.awt.event.KeyEvent.VK_O,
				java.awt.event.InputEvent.CTRL_MASK));
		fileOpen.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				// function call

			}
		});
		fileOpen.setToolTipText("Click to open the file");

		fileExit.setText(" Exit");
		// fileExit.setIcon(new
		// javax.swing.ImageIcon(getClass().getResource("cse/uta/edu/Images/exit.png")));
		fileExit.setToolTipText("Exit the Application");
		fileExit.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				System.exit(0);

			}
		});

		helpAbout.setText(" About");
		// helpAbout.setIcon(new javax.swing.ImageIcon(getClass().getResource(
		// "cse/uta/edu/Images/about.gif")));
		helpAbout.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				JOptionPane.showMessageDialog(frame, aboutApplication);

			}
		});

		// adding the menu items to menu
		fileMenu.add(fileOpen);
		fileMenu.addSeparator();
		fileMenu.add(fileExit);
		helpMenu.add(helpAbout);
		fileMenu.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
		helpMenu.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
		// adding menu to menu bar
		menuBar.add(fileMenu);
		menuBar.add(helpMenu);

		// addding menubar to the window
		frame.setJMenuBar(menuBar);

		// ToolBar Components
		toolBar.setFloatable(false);

		openFileBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource(
				"/cse/uta/edu/Images/open_project_24.png")));
		openFileBtn.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1,
				1, 4));
		newFileBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource(
				"/cse/uta/edu/Images/new_project_24.png")));
		newFileBtn.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1,
				1, 4));
		infoHelpBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource(
				"/cse/uta/edu/Images/help2.jpg")));
		infoHelpBtn.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1,
				1, 4));

		toolBar.addSeparator();
		toolBar.add(newFileBtn);
		toolBar.add(openFileBtn);
		toolBar.add(infoHelpBtn);

		// LeftPanel components definitions
		treeHeaderLabel.setText("System View");
		treeHeaderLabel.setHorizontalAlignment(SwingConstants.CENTER);
		treeHeaderLabel.setBorder(new CompoundBorder(BorderFactory
				.createBevelBorder(BevelBorder.RAISED), new EmptyBorder(5, 5,
				5, 5)));

		root.add(sourceCode);
		root.add(inputparametermodel);
		root.add(initialTestCase);
		inputparametermodel.add(parameters);
		inputparametermodel.add(constraints);
		tree.getSelectionModel().setSelectionMode(
				TreeSelectionModel.SINGLE_TREE_SELECTION);
		/*
		 * to be implemented later GroupLayout layout = new
		 * GroupLayout(leftPanel); leftPanel.setLayout(layout);
		 */

		// Tree to Tab reflection logic -- when a node is selected on Tree,
		// corresponding tab will become active
		tree.addTreeSelectionListener(new TreeSelectionListener() {

			@Override
			public void valueChanged(TreeSelectionEvent e) {
				DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree
						.getLastSelectedPathComponent();
				if (selectedNode.isLeaf()) {
					String nodeSelected = selectedNode.toString();
					if (nodeSelected == "Source Code"
							&& mainTab.getSelectedIndex() != 0) {
						mainTab.setSelectedIndex(0);
					}
					if (nodeSelected == "Initial Test Case"
							&& mainTab.getSelectedIndex() != 1) {
						mainTab.setSelectedIndex(1);
					}

					if (nodeSelected == "Parameters") {
						mainTab.setSelectedIndex(2);
						innerSpecificationTab.setSelectedIndex(0);
					}

					if (nodeSelected == "Constraints") {
						mainTab.setSelectedIndex(2);
						innerSpecificationTab.setSelectedIndex(1);
					}
				}

			}
		});

		// Tab to tree reflection logic starts
		// to be implemented later
		// logic ends here

		leftPanel.setLayout(new BorderLayout());
		leftPanel.add(treeHeaderLabel, BorderLayout.NORTH);
		leftPanel.add(tree, BorderLayout.CENTER);

		splitPane.setLeftComponent(leftPanel);
		splitPane.setRightComponent(mainTab);

		frame.add(toolBar, BorderLayout.NORTH);
		frame.add(splitPane, BorderLayout.CENTER);

		// GUI Part ends

		// functionality part begins
		openFileBtn.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				/*
				 * inner comment starts String str; String spv; String str1;
				 * String str2; String strTest; String strResults; String
				 * result; ArrayList <String> constraints = new
				 * ArrayList<String>(); ArrayList <String> pname = new
				 * ArrayList<String>(); ArrayList <String> pvalues = new
				 * ArrayList<String>(); ArrayList <String> testValues = new
				 * ArrayList<String>(); ArrayList <String> tResults = new
				 * ArrayList<String>(); inner comments ends here
				 */
				JFileChooser f1 = new JFileChooser();
				// fileInfo obj = new fileInfo();
				ArrayList<String> parameters_name = new ArrayList<String>();
				ArrayList<String> parameters_value = new ArrayList<String>();
				ArrayList<String> testResult_value = new ArrayList<String>();
				ArrayList<Parameter> parameters_initialForm = new ArrayList<Parameter>();
				// TestSet ts_initialForm = new TestSet();
				// ArrayList <int[]> parametersValue_Count = new
				// ArrayList<int[]>();

				int returnVal = f1.showOpenDialog(frame);
				if (returnVal == JFileChooser.APPROVE_OPTION) {
					File file = f1.getSelectedFile();

					ipFileName = file.getAbsolutePath().toString();

					opNewTC = f1.getCurrentDirectory().toString()
							+ "\newTC.txt";
					opSusCombo = f1.getCurrentDirectory().toString()
							+ "\newSuspiciousCombo.txt";

					/*
					 * CFL1 newObj = new CFL1();
					 * newObj.startAlgorithm(ipFileName, opSusCombo, opNewTC);
					 */

					SUT sut = new SUT();
					sut = (new SUTInfoReader(ipFileName)).getSUT();

					// System.out.println("Testing Testing....\n "+ sut);

					// Parameters

					parameters_initialForm = sut.getParameters();

					for (Parameter p : parameters_initialForm) {
						parameters_name.add(p.getName());
						parameters_value.add(p.getValues().toString());

					}

					for (int i = 0; i < parameters_initialForm.size(); i++) {
						System.out.println(parameters_name.get(i).toString()
								+ ":\t" + parameters_value.get(i).toString());
						i++;
					}
					// Constraints

					for (int i = 0; i < sut.getConstraints().size(); i++) {
						System.out.println(sut.getConstraints().get(i)
								.toString());
						i++;
					}

					// Initial Test Results
					System.out.println("Initial Test Set: \n"
							+ sut.getTs().toString());

					System.out.println("Testing:"
							+ sut.getTs().getMatrix().size());
					for (int i = 0; i < sut.getTs().getMatrix().size(); i++) {
						System.out.println(Arrays.toString(sut.getTs()
								.getMatrix().get(i)));

					}
					int testResultSize = sut.getTs().getResult().size();
					System.out.println(testResultSize + "*****"
							+ sut.getTs().getResult().toString());

					for (int count = 0; count < testResultSize; count++) {
						testResult_value.add(sut.getTs().getResult().get(count)
								.toString());
					}

					for (int count = 0; count < testResultSize; count++) {
						if (testResult_value.get(count).toString()
								.equalsIgnoreCase("1")) {
							System.out.println("Pass");
						}

						else {
							System.out.println("fail");
						}
					}
					// System.out.println("Testing output file" + a);
					// obj.setIpTestFile(a);
					// System.out.println("Test Run # 2" + obj.getIpTestFile());
					/*
					 * BufferedReader br; try { br = new BufferedReader(new
					 * FileReader(file));
					 * 
					 * while((str1 = br.readLine())!=null) { // Parameters logic
					 * starts if(str1.startsWith("Parameters:")) { while ((str1
					 * = br.readLine()) != null) { if(str1.length()==0) { break;
					 * } //end if
					 * 
					 * str1 = str1.replace("\"", ""); Pattern paramPattern =
					 * Pattern.compile(":"); String[] tokens =
					 * paramPattern.split(str1); str =
					 * tokens[0].toString()+"\n"; pname.add(str); tokens[1] =
					 * tokens[1].replace("[", ""); tokens[1] =
					 * tokens[1].replace("]", ""); spv =
					 * tokens[1].toString()+"\n"; pvalues.add(spv); } } //
					 * Parameters logic ends
					 * 
					 * if(str1.startsWith("Constraints :")) {
					 * //System.out.println("Printing the Constraints used:");
					 * while ((str1 = br.readLine()) != null) {
					 * //System.out.println(str1); if(str1.length()==0) { break;
					 * } //end if
					 * 
					 * str2 = str1+"\n"; constraints.add(str2);
					 * System.out.println(str1);
					 * System.out.println("*******************");
					 * System.out.println(str2);
					 * System.out.println("/././././...//////"); } // end while
					 * }//end main - if for constraints
					 * 
					 * if(str1.startsWith("Tests")) { while ((str1 =
					 * br.readLine()) != null) { if(str1.length()==0) { break; }
					 * //end if strTest = str1+"\n"; testValues.add(strTest);
					 * 
					 * } // end while } // Test table logic ends
					 * 
					 * //To add - error msg dialog box
					 * if(str1.startsWith("Test #")) { while ((str1 =
					 * br.readLine()) != null) { if(str1.length()==0) { break; }
					 * //end if Pattern resultPattern = Pattern.compile(",");
					 * String[] tokens = resultPattern.split(str1); result =
					 * tokens[1].toString()+"\n"; tResults.add(result);
					 * 
					 * } // end while } // Test table logic ends
					 * 
					 * if(str1.startsWith("Relations :")) {
					 * //System.out.println("Printing the Relations used:");
					 * while ((str1 = br.readLine()) != null) {
					 * if(str1.length()==0) { break; } //end if str1 =
					 * str1.replace("\"", ""); Pattern paramPattern =
					 * Pattern.compile(","); String[] strength =
					 * paramPattern.split(str1); strength[0] =
					 * strength[0].replace("[", ""); //int strength_Testset =
					 * Integer.parseInt(strength[0]);
					 * //System.out.println(strength1); if(strength[0]!= null) {
					 * System.out.println("Strength:" + strength[0]);
					 * //rLabel.setText("Strength of the Test Set:  " +
					 * strength[0] ); } else {
					 * JOptionPane.showMessageDialog(frame,
					 * "Input file must have Test Strength, Please choose another file"
					 * );
					 * 
					 * } } // end while }//end main - if for relations
					 * 
					 * 
					 * } // end of "While" main
					 * 
					 * //updating the table logic starts
					 * 
					 * String[] columnName = {"Constraints"}; String[]
					 * rTableColumnName =
					 * {"Test #",testValues.get(0),"Results"}; //Constraints
					 * Table
					 * 
					 * constraintsTable.setColumnCount(0);
					 * constraintsTable.setRowCount(0);
					 * 
					 * 
					 * for(int col=0;col<columnName.length;col++) {
					 * constraintsTable.addColumn(columnName[col]); }
					 * 
					 * for(int r=0;r<constraints.size();r++) {
					 * 
					 * constraintsTable.insertRow(r, new
					 * Object[]{constraints.get(r)}); }
					 * 
					 * 
					 * //Parameter information Table pTable.setColumnCount(0);
					 * pTable.setRowCount(0);
					 * 
					 * for(int col=0;col<pnameArray.length;col++) {
					 * pTable.addColumn(pnameArray[col]); }
					 * 
					 * // Adding rows to the table for(int row
					 * =0;row.size();row++) { pTable.insertRow(row,new
					 * Object[]{pname.get(row),pvalues.get(row)});
					 * //System.out.println
					 * (pname.get(row)+"\n"+pvalues.get(row)); }
					 * 
					 * // Test Values table testresultTable.setColumnCount(0);
					 * testresultTable.setRowCount(0);
					 * 
					 * for(int col=0;col<rTableColumnName.length;col++) {
					 * testresultTable.addColumn(rTableColumnName[col]); }
					 * 
					 * for(int row=0;row<testValues.size();row++) {
					 * 
					 * testresultTable.insertRow(row, new
					 * Object[]{row+1,testValues.get(row+1),tResults.get(row)});
					 * 
					 * }
					 * 
					 * 
					 * 
					 * // updating the table logic ends
					 * 
					 * }
					 * 
					 * catch (FileNotFoundException e1) { // TODO Auto-generated
					 * catch block e1.printStackTrace(); }
					 * 
					 * 
					 * 
					 * catch (Exception e1) { // TODO Auto-generated catch block
					 * e1.printStackTrace(); }
					 * 
					 * 
					 * }
					 * 
					 * 
					 * 
					 * 
					 * }
					 * 
					 * });
					 */
					// comments end here
				}
			}
		});
	}
}